home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 July
/
EnigmA AMIGA RUN 20 (1997)(G.R. Edizioni)(IT)[!][issue 1997-07 & 08][EAR-CD IV].iso
/
earcd
/
dev
/
c
/
asyncio.lha
/
AsyncIO
/
src
/
WaitPacket.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-02-18
|
3KB
|
79 lines
#include "async.h"
/* this function waits for a packet to come back from the file system. If no
* packet is pending, state from the previous packet is returned. This ensures
* that once an error occurs, it state is maintained for the rest of the life
* of the file handle.
*
* MH: The above causes one minor problem though. SeekAsync() past EOF
* (can?) cause the file to be stuck in an error state, while DOS would
* allow file operations to continue anyway, based on the EOF position.
* This is mostly a compatibility problem though, and we've never said
* SeekAsync() was behaving just like Seek(). :) Fixing this isn't trivial,
* since it is hard to tell (AFAIK) if we really are at EOF, or a Seek() or
* a read failed due to other problems.
*
* This function also deals with IO errors, bringing up the needed DOS
* requesters to let the user retry an operation or cancel it.
*/
LONG
AS_WaitPacket( AsyncFile *file )
{
#ifdef ASIO_NOEXTERNALS
struct ExecBase *SysBase = file->af_SysBase;
struct DosLibrary *DOSBase = file->af_DOSBase;
#endif
LONG bytes;
if( file->af_PacketPending )
{
while( TRUE )
{
/* This enables signalling when a packet comes back to the port */
file->af_PacketPort.mp_Flags = PA_SIGNAL;
/* Wait for the packet to come back, and remove it from the message
* list. Since we know no other packets can come in to the port, we can
* safely use Remove() instead of GetMsg(). If other packets could come in,
* we would have to use GetMsg(), which correctly arbitrates access in such
* a case
*/
Remove( ( struct Node * ) WaitPort( &file->af_PacketPort ) );
/* set the port type back to PA_IGNORE so we won't be bothered with
* spurious signals
*/
file->af_PacketPort.mp_Flags = PA_IGNORE;
/* mark packet as no longer pending since we removed it */
file->af_PacketPending = FALSE;
bytes = file->af_Packet.sp_Pkt.dp_Res1;
if( bytes >= 0 )
{
/* packet didn't report an error, so bye... */
return( bytes );
}
/* see if the user wants to try again... */
if( ErrorReport( file->af_Packet.sp_Pkt.dp_Res2, REPORT_STREAM, file->af_File, NULL ) )
{
return( -1 );
}
/* user wants to try again, resend the packet */
AS_SendPacket( file,
file->af_Buffers[ file->af_ReadMode ?
file->af_CurrentBuf :
1 - file->af_CurrentBuf ] );
}
}
/* last packet's error code, or 0 if packet was never sent */
SetIoErr( file->af_Packet.sp_Pkt.dp_Res2 );
return( file->af_Packet.sp_Pkt.dp_Res1 );
}